const fs = require('fs');
const gulp = require('gulp');
const server = require('gulp-develop-server');
const browserSync = require('browser-sync').create();
const config = require('./config');

const through = require('through2');
const rev = require('gulp-rev');
const useref = require('gulp-useref');
const gulpif = require('gulp-if');
const uglify = require('gulp-uglify');
const csso = require('gulp-csso');
const del = require('del');
const assetManifest = require('gulp-asset-manifest');
const livereload = require('gulp-livereload');

const configPath = __dirname + '/config';
const bowerPath = __dirname + '/bower_components';
const publicPath = __dirname + '/public';
const clientPath = __dirname + '/client';
const distPath = __dirname + '/dist';
const adminSrcPath = __dirname + '/client/admin';
const adminDistPath = __dirname + '/dist/admin';
const frontSrcPath = __dirname + '/client/front';
const frontDistPath = __dirname + '/dist/front';

/**
 * 构建 Admin
 */
gulp.task('bower&templates', function () {
    let libs = ['ueditor', 'PACE', 'jstree', 'requirejs', 'unserialize'];
    for (let i in libs) {
        let lib = libs[i];
        del.sync([publicPath + '/' + lib + '/**/*'], {force: true});
        gulp.src(bowerPath + '/' + lib + '/**/*.*').pipe(gulp.dest(publicPath + '/' + lib));
    }
    del.sync([distPath + '/templates/**/*'], {force: true});
    gulp.src(clientPath + '/templates/**/*.*').pipe(gulp.dest(distPath + '/templates'));
});

gulp.task('Admin-1', function () {
    del.sync([distPath + '/admin/**/*'], {force: true});
    gulp.src(bowerPath + '/bootstrap/dist/fonts/**/*.*').pipe(gulp.dest(adminDistPath + '/fonts'));
    gulp.src(bowerPath + '/font-awesome/fonts/**/*.*').pipe(gulp.dest(adminDistPath + '/fonts'));
    gulp.src(clientPath + '/admin/images/**/*.*').pipe(gulp.dest(adminDistPath + '/images'));
    gulp.src(clientPath + '/admin/mp3/**/*.*').pipe(gulp.dest(adminDistPath + '/mp3'));

    return gulp.src(adminSrcPath + '/scripts/*.js').pipe(rev()).pipe(uglify())
        .pipe(assetManifest({bundleName: 'scripts_01', manifestFile: configPath + '/asset_admin.json'}))
        .pipe(gulp.dest(adminDistPath + '/scripts'));
});
gulp.task('Admin-2', ['Admin-1'], function () {
    return gulp.src(adminSrcPath + '/*/*.handlebars')
        .pipe(useref({
            searchPath: bowerPath,
            transformPath: function (filePath) {
                if (filePath.indexOf('/scripts/') != -1 || filePath.indexOf('/styles/') != -1) {
                    return filePath.replace('bower_components', 'client/admin');
                }
                return filePath;
            }
        }))
        .pipe(gulpif('*.js', uglify()))
        .pipe(gulpif('*.js', rev()))
        .pipe(gulpif('*.js', assetManifest({bundleName: 'scripts', manifestFile: configPath + '/asset_admin.json'})))
        .pipe(gulpif('*.css', csso()))
        .pipe(gulpif('*.css', rev()))
        .pipe(gulpif('*.css', assetManifest({bundleName: 'styles', manifestFile: configPath + '/asset_admin.json'})))
        .pipe(gulp.dest(adminDistPath));
});
gulp.task('Admin:start', ['Admin-2'], function () {
    return gulp.src(adminDistPath + '/*/*.handlebars').pipe(function () {
        let assetMap = {};
        let {scripts, styles, scripts_01} = require(configPath + '/asset_admin.json');
        for (let i in scripts_01) {
            let script = scripts_01[i];
            assetMap['/scripts/' + script.split('-')[0]] = "{{or settings.cdn ''}}/scripts/" + script.replace('.js', '');
        }
        for (let i in scripts) {
            let script = scripts[i];
            assetMap['/scripts/' + script.split('-')[0]] = "{{or settings.cdn ''}}/scripts/" + script.replace('.js', '');
        }
        for (let i in styles) {
            let style = styles[i];
            assetMap['/styles/' + style.split('-')[0]] = "{{or settings.cdn ''}}/styles/" + style.replace('.css', '');
        }
        return through.obj(function (file, enc, cb) {
            if (file.isNull()) {
                return cb(null, file);
            }
            if (file.isBuffer()) {
                let content = file.contents.toString('utf8');
                for (let i in assetMap) {
                    let v = assetMap[i];
                    content = content.replace(i, v);
                }
                fs.writeFile(adminDistPath + '/' + file.relative, content, {
                    mode: file.stat.mode
                }, function (err) {
                    if (err) {
                        return console.log(err);
                    }
                });
            }
            cb(null, file);
        });
    }());
});

/**
 * 构建 Front
 */
gulp.task('Front-1', function () {
    del.sync([frontDistPath + '/**/*'], {force: true});
    return gulp.src(frontSrcPath + '/**/*').pipe(gulp.dest(distPath + '/front'));
});
gulp.task('Front-2', ['Front-1'], function () {
    return gulp.src(frontSrcPath + '/*/*.handlebars')
        .pipe(useref({
            searchPath: frontSrcPath
        }))
        .pipe(gulpif('*.js', uglify()))
        .pipe(gulpif('*.js', rev()))
        .pipe(gulpif('*.js', assetManifest({bundleName: 'scripts', manifestFile: configPath + '/asset_front.json'})))
        .pipe(gulpif('*.css', csso()))
        .pipe(gulpif('*.css', rev()))
        .pipe(gulpif('*.css', assetManifest({bundleName: 'styles', manifestFile: configPath + '/asset_front.json'})))
        .pipe(gulp.dest(frontDistPath));
});
gulp.task('Front:start', ['Front-2'], function () {
    return gulp.src(frontDistPath + '/*/*.handlebars').pipe(function () {
        let assetMap = {};
        let {scripts, styles} = require(configPath + '/asset_front.json');
        for (let i in scripts) {
            let script = scripts[i];
            assetMap['/js/' + script.split('-')[0]] = "{{or settings.cdn ''}}/js/" + script.replace('.js', '');
        }
        for (let i in styles) {
            let style = styles[i];
            assetMap['/css/' + style.split('-')[0]] = "{{or settings.cdn ''}}/css/" + style.replace('.css', '');
        }
        return through.obj(function (file, enc, cb) {
            if (file.isNull()) {
                return cb(null, file);
            }
            if (file.isBuffer()) {
                let content = file.contents.toString('utf8');
                for (let i in assetMap) {
                    let v = assetMap[i];
                    content = content.replace(i, v);
                }
                fs.writeFile(frontDistPath + '/' + file.relative, content, {
                    mode: file.stat.mode
                }, function (err) {
                    if (err) {
                        return console.log(err);
                    }
                });
            }
            cb(null, file);
        });
    }());
});

/**
 * 启动服务器
 */
gulp.task('server', function () {
    gulp.watch(['src/**'], server.restart);
    server.listen({path: './src/app.js'});
});

/**
 * 启动服务器
 */
gulp.task('server_data', function () {
    gulp.watch(['src/**'], server.restart);
    server.listen({path: './src/app_data.js'});
});

/**
 * 自动刷新网页
 */
gulp.task('browser-sync', function () {
    browserSync.init({
        port: 1212,
        open: 'external',
        ws: true,
        notify: false,
        proxy: 'localhost:' + config.port,
        files: ['client/**']
    });
});

/**
 * 默认启动服务器
 */
gulp.task('default', ['server', 'browser-sync']);
